//
//  JJVoiceConvertWordHelper.swift
//  swiftProject
//
//  Created by yangjian on 2021/12/10.
//

import UIKit

import Speech

class JJVoiceConvertWordTask : NSObject {
    var filePath = ""
    var convertingBlock : ((SFTranscription) -> Void)!
    var completion : ((SFSpeechRecognitionResult?,Error?) -> Void)!
    var recognitionTask : SFSpeechRecognitionTask?
    var result : SFSpeechRecognitionResult?
}

class JJVoiceConvertWordHelper : NSObject{
    static let share = JJVoiceConvertWordHelper()

    var converting = false
    var tasks = [JJVoiceConvertWordTask].init()
    var currentTask : JJVoiceConvertWordTask?
    
    //.wav格式!
    func addVoiceFileConvertWordTask(filePath:String,
                                     convertingBlock:@escaping((SFTranscription) -> Void),
                                     completion:@escaping((SFSpeechRecognitionResult?,Error?) -> Void)) {
        let newTask = JJVoiceConvertWordTask.init()
        newTask.filePath = filePath
        newTask.convertingBlock = convertingBlock
        newTask.completion = completion
        self.tasks.append(newTask)
        self.begin()
    }
    
    //取消转换任务(所有)
    func cancelAllTask(){
        self.tasks.removeAll()
        self.currentTask?.recognitionTask?.cancel()
    }
    
    //全部开始
    func begin(){
        if self.converting {
            return
        }
        self.converting = true
        self.performTask()
    }
    
    //全部完成
    func end(){
        print("全部语音转换已完成")
        self.converting = false
    }
    
    //单任务开始
    func performTask(){
        if self.tasks.count == 0 {
            self.end()
        }
        self.currentTask = self.tasks.remove(at: 0)
        self.convert()
    }
    
    //单任务完成
    func finishTask(){
        print("单任务完成")
        if self.tasks.count == 0 {
            self.end()
        }else{
            performTask()
        }
    }
    
    func convert(){
        guard let currentTask = self.currentTask else {
            return
        }
        let recognitionRequest = SFSpeechURLRecognitionRequest.init(url: URL.init(fileURLWithPath: currentTask.filePath))
        let recongnizer = SFSpeechRecognizer.init(locale: Locale.init(identifier: "zh_CN"))
        self.currentTask?.recognitionTask = recongnizer?.recognitionTask(with: recognitionRequest, delegate: self)
    }
}

extension JJVoiceConvertWordHelper:SFSpeechRecognitionTaskDelegate{
    // Called when the task first detects speech in the source audio
    func speechRecognitionDidDetectSpeech(_ task: SFSpeechRecognitionTask) {
        guard let currentTask = self.currentTask else {
            return
        }
        if task != currentTask.recognitionTask {
            return
        }
        print("speechRecognitionDidDetectSpeech")
    }

    // Called for all recognitions, including non-final hypothesis
    func speechRecognitionTask(_ task: SFSpeechRecognitionTask, didHypothesizeTranscription transcription: SFTranscription) {
        guard let currentTask = self.currentTask else {
            return
        }
        if task != currentTask.recognitionTask {
            return
        }
        print("转换中:\(transcription.formattedString)")
        self.currentTask?.convertingBlock(transcription)
        
    }
    
    // Called only for final recognitions of utterances. No more about the utterance will be reported
    func speechRecognitionTask(_ task: SFSpeechRecognitionTask, didFinishRecognition recognitionResult: SFSpeechRecognitionResult) {
        guard let currentTask = self.currentTask else {
            return
        }
        if task != currentTask.recognitionTask {
            return
        }
        print("最终结果:\(recognitionResult.bestTranscription.formattedString)")
        currentTask.result = recognitionResult
    }
    
    func speechRecognitionTaskFinishedReadingAudio(_ task: SFSpeechRecognitionTask) {
        guard let currentTask = self.currentTask else {
            return
        }
        if task != currentTask.recognitionTask {
            return
        }
        print("speechRecognitionTaskFinishedReadingAudio")
    }

    func speechRecognitionTaskWasCancelled(_ task: SFSpeechRecognitionTask) {
        guard let currentTask = self.currentTask else {
            return
        }
        if task != currentTask.recognitionTask {
            return
        }
        //停止解析
        print("speechRecognitionTaskWasCancelled")
    }

    // Called when recognition of all requested utterances is finished.
    // If successfully is false, the error property of the task will contain error information
    func speechRecognitionTask(_ task: SFSpeechRecognitionTask, didFinishSuccessfully successfully: Bool) {
        guard let currentTask = self.currentTask else {
            return
        }
        if task != currentTask.recognitionTask {
            return
        }
        print("speechRecognitionTask")
        if successfully {
            currentTask.completion(currentTask.result,nil)
        }else{
            currentTask.completion(nil,task.error)
        }
        self.finishTask()
    }
}

